package com.reebake.ideal.security.handler;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.reebake.ideal.security.entity.AuthUser;
import com.reebake.ideal.security.entity.UserDetailsEntity;
import com.reebake.ideal.security.service.UserSecurityService;
import com.reebake.ideal.security.util.AuthenticationExceptionUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.Collection;

/**
 * 通过账户加载用户认证信息
 */
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {
    private final UserSecurityService userSecurityService;

    public static AuthUser convert(String loginName, UserDetailsEntity userDetailsEntity) {
        String userId = userDetailsEntity.getUserId();
        String password = userDetailsEntity.getPassword();
        if (StrUtil.isBlank(password)) {
            password = "NONE";
        }

        Collection<String> authorities = userDetailsEntity.getAuthorities();
        Collection<SimpleGrantedAuthority> grantedAuthorities = CollectionUtil.newArrayList();
        if (CollectionUtil.isNotEmpty(authorities)) {
            for (String authority : authorities) {
                grantedAuthorities.add(new SimpleGrantedAuthority(authority));
            }
        }

        boolean enabled = userDetailsEntity.getEnabled();
        boolean accountNonExpired = userDetailsEntity.getAccountNonExpired();
        boolean credentialsNonExpired = userDetailsEntity.getCredentialsNonExpired();
        boolean accountNonLocked = userDetailsEntity.getAccountNonLocked();

        AuthUser authUser = new AuthUser(loginName, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, grantedAuthorities);
        authUser.setUserId(userId);

        return authUser;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDetailsEntity userDetailsEntity = userSecurityService.loadUserByUsername(username);
        if (ObjectUtil.isNull(userDetailsEntity)) {
            throw AuthenticationExceptionUtil.throwUserNotFound(username);
        }

        return convert(username, userDetailsEntity);
    }
}
